#include "common_modbus.h"

#ifndef NULL
#define NULL    ((void *)0)
#endif

#define ASSERT_NOTNULL(p) if (p == NULL) return (-1)

/* 
 新增modbus设备后需要通过这个函数将设备挂接到总线上，
 后续设备驱动才能通过modbus设备中的总线读写方法与设备交互
 */
int xp_modbus_device_mount(struct xp_modbus_bus *bus, struct xp_modbus_device *dev)
{
    ASSERT_NOTNULL(bus);
    ASSERT_NOTNULL(dev);
    // 检查sid防止重复挂载
    unsigned char i = 0;
    for ( ; i < bus->num_of_dev; i ++ ) {
        if (bus->sid_set[i] == dev->sid) return -1;
    }
    // 挂载设备
    xp_slist_add_tail(&bus->dev_list, &dev->dev_node);
    bus->sid_set[bus->num_of_dev] = dev->sid;
    bus->num_of_dev ++;
    dev->bus = bus;
    return 0;
}

int xp_modbus_device_unmount(struct xp_modbus_bus *bus, struct xp_modbus_device *dev)
{
    
    ASSERT_NOTNULL(bus);
    ASSERT_NOTNULL(dev);
    unsigned char i = 0, tmp = 0;
    char has_dev_flag = 0;
    for ( ; i < bus->num_of_dev; i ++) {
        if (bus->sid_set[i] == dev->sid) {
            has_dev_flag = 1;
            break;
        }
    }

    if (0 == has_dev_flag) return -1;
    xp_slist_del(&bus->dev_list, &dev->dev_node);
    for (i = 0; i < bus->num_of_dev; i ++) {
        if (bus->sid_set[i] == dev->sid) {
            bus->sid_set[i] = bus->sid_set[i+1];
            bus->sid_set[i+1] = (bus->sid_set[i] == 0) ? 0 : dev->sid;
        }
    }
    bus->num_of_dev --;
    dev->bus = (void *)0;
    
    return 0;
}

